/**
 * @file camera.c
 *
 */

/*********************
 *      INCLUDES
 *********************/
#include "lv_watch.h"

#if USE_LV_WATCH_CAMERA != 0

#include <stdio.h>
#include <stdlib.h>
#include "lv_drv_conf.h"
#include "lvgl/hal/hal.h"
#include "lv_drivers/camera/camera_api.h"
#include "lv_drivers/camera/camera_hal_core.h"
/*********************
 *      DEFINES
 *********************/


/**********************
 *      TYPEDEFS
 **********************/

/**********************
 *  STATIC PROTOTYPES
 **********************/
static void camera_prepare_destory(lv_obj_t * activity_obj);
static void camera_back_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void camera_imgview_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void camera_shoot_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void camera_create_option(lv_obj_t * obj);
static void camera_create_shoot(lv_obj_t * obj);
static void camera_preview_task(lv_task_t * task);
static void camera_out_of_memory_create(lv_obj_t * obj);
static void camera_outmem_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void camera_save_failed_create(int32_t error);
static void camera_save_failed_timer_cb(void * param);
static lv_obj_t * camera_get_obj(void);
static void camera_open_faied_warn(lv_obj_t * obj);
#if 0
static void camera_autosave_timer_func(void * param);
static lv_fs_res_t camera_save_img_capture(void);
static void camera_delete_cancel_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void camera_delete_ok_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void camera_delete_create(void);
static void camera_save_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void camera_delete_btn_event_cb(lv_obj_t * btn, lv_event_t e);
static void camera_share_btn_event_cb(lv_obj_t * btn, lv_event_t e);
#endif

/**********************
 *  STATIC VARIABLES
 **********************/
static lv_img_dsc_t img_camera;
//static lv_img_dsc_t img_capture;
static lv_task_t * preview_task = NULL;

/**********************
 *      MACROS
 **********************/

/**********************
 *   GLOBAL FUNCTIONS
***********************/
lv_obj_t * camera_create(lv_obj_t * activity_obj)
{
    if(activity_obj == NULL) {
        lv_watch_activity_ext_t activity_ext;
        _lv_memset_00(&activity_ext, sizeof(lv_watch_activity_ext_t));
        activity_ext.actId = ACT_ID_CAMERA;
        activity_ext.create = camera_create;
        activity_ext.prepare_destory = camera_prepare_destory;
        activity_obj = lv_watch_creat_activity_obj(&activity_ext);
        LV_ASSERT_MEM(activity_obj);
        if(activity_obj == NULL) return NULL;
    }

    lv_obj_t * obj = lv_watch_obj_create(activity_obj);
    LV_ASSERT_MEM(obj);
    if(obj == NULL) return NULL;
    lv_watch_obj_set_anim_mode(obj, LV_WATCH_ANIM_HOR_RIGHT_HIDE);

    lv_camera_obj_ext_t * ext = lv_obj_allocate_ext_attr(obj, sizeof(lv_camera_obj_ext_t));
    LV_ASSERT_MEM(ext);
    if(ext == NULL) return NULL;
    if(!WATCH_HAS_WALLPAPER) {
        lv_obj_t * img = lv_img_create(activity_obj, NULL);
        LV_ASSERT_MEM(img);
        if(img == NULL) return NULL;
        lv_img_set_src(img, watch_get_bg());
        lv_obj_set_size(img, LV_HOR_RES, LV_VER_RES);

        lv_obj_t * par = lv_obj_get_parent(obj);
        lv_obj_set_parent(obj, img);
        lv_obj_del(par);
    }

    ext->img = lv_obj_get_parent(obj);
    ext->timer = NULL;

    ext->cont = lv_cont_create(obj, NULL);
    lv_obj_set_size(ext->cont, LV_HOR_RES, LV_VER_RES);
    lv_obj_set_style_local_bg_color(ext->cont, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK);
    lv_obj_set_hidden(ext->cont, true);

    lv_img_cache_invalidate_src(&img_camera);
    img_camera.header.always_zero = 0;
    img_camera.header.w = lv_obj_get_width(lv_obj_get_parent(obj));
    img_camera.header.h = lv_obj_get_height(lv_obj_get_parent(obj));
    img_camera.data_size = img_camera.header.w * img_camera.header.h * LV_COLOR_SIZE / 8;
    img_camera.header.cf = LV_IMG_CF_TRUE_COLOR;
    img_camera.data = lv_mem_alloc(img_camera.header.w * img_camera.header.h * LV_COLOR_SIZE / 8);
    LV_ASSERT_MEM(img_camera.data);
    if(img_camera.data == NULL) return NULL;
    memset((void *)img_camera.data, 0, img_camera.header.w * img_camera.header.h * LV_COLOR_SIZE / 8);

    camera_create_shoot(obj);
    camera_create_option(obj);

    cam_start_preview_t cam_params;

    cam_params.width = 240;
    cam_params.height = 240;
    cam_params.sensor_id = 0;
    int ret = Hal_Camera_Start_Preview(&cam_params);
    if(ret != 0) {
        camera_open_faied_warn(obj);
        return obj;
    }

    preview_task = lv_task_create(camera_preview_task, 500, LV_TASK_PRIO_HIGH, NULL);

    return obj;
}

void camera_create_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;

    if(LV_EVENT_CLICKED == e)
    {
        lv_watch_png_cache_all_free();

        album_photo_ll_init();
        album_load_photo_path();
        lv_obj_t * obj = camera_create(NULL);
        LV_ASSERT_MEM(obj);
    }
}

void camera_start_from_album(void)
{
    lv_obj_t * obj = camera_get_obj();

//  lv_img_cache_invalidate_src(&img_capture);
    img_camera.header.always_zero = 0;
    img_camera.header.w = lv_obj_get_width(lv_obj_get_parent(obj));
    img_camera.header.h = lv_obj_get_height(lv_obj_get_parent(obj));
    img_camera.data_size = img_camera.header.w * img_camera.header.h * LV_COLOR_SIZE / 8;
    img_camera.header.cf = LV_IMG_CF_TRUE_COLOR;
    img_camera.data = lv_mem_alloc(img_camera.header.w * img_camera.header.h * LV_COLOR_SIZE / 8);
    LV_ASSERT_MEM(img_camera.data);
    if(img_camera.data == NULL) return;
    memset((void *)img_camera.data, 0, img_camera.header.w * img_camera.header.h * LV_COLOR_SIZE / 8);

    lv_camera_obj_ext_t * ext = lv_obj_get_ext_attr(obj);
    lv_obj_set_hidden(ext->img, false);

    cam_start_preview_t cam_params;
    cam_params.width = 240;
    cam_params.height = 240;
    cam_params.sensor_id = 0;
    int ret = Hal_Camera_Start_Preview(&cam_params);
    if(ret != 0) {
        camera_open_faied_warn(obj);
        return;
    }
    preview_task = lv_task_create(camera_preview_task, 500, LV_TASK_PRIO_HIGH, NULL);

    //delete the black temp obj
    lv_obj_set_hidden(ext->cont, true);
}

/**********************
 *   STATIC FUNCTIONS
 **********************/
static lv_obj_t * camera_get_activity_obj(void)
{
    lv_obj_t * activity_obj = lv_watch_get_activity_obj(ACT_ID_CAMERA);

    return activity_obj;
}

static lv_obj_t * camera_get_obj(void)
{
    lv_obj_t * watch_obj = NULL;

    lv_obj_t * activity_obj = camera_get_activity_obj();
    if(activity_obj) {
        lv_watch_get_child_obj(activity_obj, lv_watch_obj_signal, &watch_obj);
    }
    return watch_obj;
}

static lv_camera_obj_ext_t * camera_get_ext(void)
{
    lv_camera_obj_ext_t  * ext = NULL;

    lv_obj_t * watch_obj = camera_get_obj();
    if(watch_obj) {
        ext = lv_obj_get_ext_attr(watch_obj);
    }

    return ext;
}

static void camera_open_faied_timer_cb(void * param)
{
    lv_obj_t * camera_obj = lv_watch_get_activity_obj(ACT_ID_CAMERA);
    if(camera_obj == NULL)
        return;

    lv_camera_obj_ext_t * ext = camera_get_ext();
    ext->timer = NULL;
    lv_mem_free(img_camera.data);
    img_camera.data = NULL;
    album_photo_ll_destroy();
    lv_obj_del(camera_obj);
}

static void camera_open_faied_warn(lv_obj_t * obj)
{
    lv_obj_t * cont_bg = lv_cont_create(obj, NULL);
    lv_obj_set_size(cont_bg, LV_HOR_RES, LV_VER_RES);
    lv_obj_add_style(cont_bg, LV_CONT_PART_MAIN, &lv_watch_black_tight);

    lv_obj_t * img_fail = lv_img_create(cont_bg, NULL);
    lv_img_set_src(img_fail, ICON_CANCEL);
    lv_obj_align(img_fail, NULL, LV_ALIGN_IN_TOP_MID, 0, 30);

    lv_obj_t * label = lv_label_create(cont_bg, NULL);
    lv_label_set_text_id(label, WATCH_TETX_ID_CAM_OPEN_FAILED);
    lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font30);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
    lv_obj_set_width(label, LV_HOR_RES - 20);
    lv_obj_align(label, img_fail, LV_ALIGN_OUT_BOTTOM_MID, 0, lv_font_get_line_height(&lv_font_ttf_30));

    lv_camera_obj_ext_t * ext = camera_get_ext();
    ext->timer = Hal_Timer_Start(1000, camera_open_faied_timer_cb, cont_bg, false);
}

static void camera_create_option(lv_obj_t * obj)
{
    lv_obj_t * back_btn = lv_img_create(obj, NULL);
    lv_img_set_src(back_btn, ICON_ALBUM_BACK);
    lv_obj_set_event_cb(back_btn, camera_back_btn_event_cb);
    lv_obj_set_click(back_btn, true);
    lv_watch_obj_add_element(back_btn);
    if(lv_obj_get_base_dir(obj) == LV_BIDI_DIR_RTL) {
        lv_obj_align(back_btn, obj, LV_ALIGN_IN_TOP_RIGHT, 0, 0);
        lv_img_set_angle(back_btn, 1800);
    } else
        lv_obj_align(back_btn, obj, LV_ALIGN_IN_TOP_LEFT, 0, 0);

    lv_obj_t * imgview_btn = lv_img_create(obj, NULL);
    lv_img_set_src(imgview_btn, ICON_CAMERA_IMGVIEW);
    lv_obj_set_click(imgview_btn, true);
    lv_obj_set_event_cb(imgview_btn, camera_imgview_btn_event_cb);
    lv_watch_obj_add_element(imgview_btn);
    if(lv_obj_get_base_dir(obj) == LV_BIDI_DIR_RTL)
        lv_obj_align(imgview_btn, obj, LV_ALIGN_IN_TOP_LEFT, 0, 0);
    else
        lv_obj_align(imgview_btn, obj, LV_ALIGN_IN_TOP_RIGHT, 0, 0);
}

static void camera_create_shoot(lv_obj_t * obj)
{
    lv_camera_obj_ext_t * ext = camera_get_ext();

    //update the src of img.
    lv_img_set_src(ext->img, &img_camera);

    lv_obj_t * btn;
    btn = lv_imgbtn_create(obj, NULL);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_RELEASED, ICON_CAMERA_SHOOT);
    lv_imgbtn_set_src(btn, LV_BTN_STATE_PRESSED, ICON_CAMERA_SHOOT);
    //lv_btn_set_toggle(btn, false);
    lv_obj_set_event_cb(btn, camera_shoot_btn_event_cb);
    lv_watch_obj_add_element(btn);
    lv_obj_align(btn, obj, LV_ALIGN_IN_BOTTOM_MID, 0, -20);
}

#if 0
static void camera_create_confirm_cancel(lv_obj_t * obj)
{
    lv_obj_clean(obj);

    lv_obj_t * del_btn = lv_imgbtn_create(obj, NULL);
    lv_imgbtn_set_src(del_btn, LV_BTN_STATE_RELEASED, ICON_ALBUM_DELETE_GRAY);
    lv_imgbtn_set_src(del_btn, LV_BTN_STATE_PRESSED, ICON_ALBUM_DELETE_GRAY);
    lv_obj_set_event_cb(del_btn, camera_delete_btn_event_cb);
    lv_watch_obj_add_element(del_btn);
    lv_obj_align(del_btn, obj, LV_ALIGN_IN_TOP_RIGHT, 0, 0);

    lv_obj_t * share_btn = lv_btn_create(obj, NULL);
    lv_obj_set_size(share_btn, 100, 50);
    lv_obj_set_style_local_bg_color(share_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x47, 0xA6, 0xFF));
    lv_obj_set_style_local_radius(share_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 30);
    lv_obj_set_style_local_bg_color(share_btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_COLOR_MAKE(0x47, 0xA6, 0xFF));
    lv_obj_set_style_local_radius(share_btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 30);
    lv_obj_set_event_cb(share_btn, camera_share_btn_event_cb);
    lv_watch_obj_add_element(share_btn);
    lv_obj_align(share_btn, obj, LV_ALIGN_IN_BOTTOM_LEFT, 10, -10);
    //lv_btn_set_toggle(share_btn, false);
    lv_obj_t * share_label = lv_label_create(share_btn, NULL);
    lv_label_set_text_id(share_label, WATCH_TEXT_ID_SHARE);
    lv_obj_add_style(share_label, LV_LABEL_PART_MAIN, &lv_watch_font30);

    lv_obj_t * save_btn = lv_btn_create(obj, share_btn);
    lv_obj_set_style_local_bg_color(save_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x2F, 0xC8, 0x55));
    lv_obj_set_style_local_radius(save_btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 30);
    lv_obj_set_style_local_bg_color(save_btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_COLOR_MAKE(0x2F, 0xC8, 0x55));
    lv_obj_set_style_local_radius(save_btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 30);
    lv_obj_set_event_cb(save_btn, camera_save_btn_event_cb);
    lv_watch_obj_add_element(save_btn);
    lv_obj_align(save_btn, obj, LV_ALIGN_IN_BOTTOM_RIGHT, -10, -10);
    lv_obj_t * save_label = lv_label_create(save_btn, share_label);
    lv_label_set_text_id(save_label, WATCH_TEXT_ID_SAVE);

    lv_camera_obj_ext_t * ext = camera_get_ext();
    ext->timer =  Hal_Timer_Start(3000, camera_autosave_timer_func, obj, false);
}
#endif

static void camera_out_of_memory_create(lv_obj_t * obj)
{
    lv_obj_t * cont_bg = lv_cont_create(obj, NULL);
    lv_obj_set_size(cont_bg, LV_HOR_RES, LV_VER_RES);
    lv_obj_add_style(cont_bg, LV_CONT_PART_MAIN, &lv_watch_black_tight);

    lv_obj_t * img_mem = lv_img_create(cont_bg, NULL);
    lv_img_set_src(img_mem, ICON_CAMERA_MEMORY);
    lv_obj_align(img_mem, NULL, LV_ALIGN_IN_TOP_MID, 0, 10);

    lv_obj_t * label = lv_label_create(cont_bg, NULL);
    lv_label_set_text_id(label, WATCH_TEXT_ID_OUT_OF_MEM);
    lv_label_set_long_mode(label, LV_LABEL_LONG_BREAK);
    lv_obj_set_width(label, LV_HOR_RES - 50);
    lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_obj_align(label, img_mem, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

    lv_obj_t * btn = lv_btn_create(cont_bg, NULL);
    lv_obj_set_style_local_bg_color(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x47, 0xA6, 0xFF));
    lv_obj_set_style_local_radius(btn, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 30);
    lv_obj_set_style_local_bg_color(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_COLOR_MAKE(0x47, 0xA6, 0xFF));
    lv_obj_set_style_local_radius(btn, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 30);
    lv_obj_set_size(btn, 200, 56);
    lv_obj_set_event_cb(btn, camera_outmem_btn_event_cb);
    lv_obj_align(btn, label, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);
    lv_obj_t * btn_label = lv_label_create(btn, NULL);
    lv_label_set_text_id(btn_label, WATCH_TEXT_ID_GOT_IT);
    lv_obj_add_style(btn_label,LV_LABEL_PART_MAIN, &lv_watch_font30);
}

#if 0
static lv_fs_res_t camera_save_img_capture(void)
{
    album_photo_info_t * pnode = NULL;
    static uint8_t r_num = 0;
    lv_camera_obj_ext_t * ext = camera_get_ext();
    pnode = (album_photo_info_t *)_lv_ll_ins_tail((lv_ll_t *)album_get_photo_ll());
    if(pnode == NULL) {
        camera_out_of_memory_create(camera_get_obj());
        if(img_capture.data) {
            lv_mem_aligned_free((void *)img_capture.data);
            img_capture.data = NULL;
        }
        return LV_FS_RES_UNKNOWN;
    }
    char name_str[PHOTO_PATH_LEN + 1];
    memset(name_str, 0, PHOTO_PATH_LEN + 1);
    pnode->selected = 0;
    pnode->size = img_capture.data_size;
    pnode->index = album_photo_ll_get_nodecnt() - 1;
    snprintf(name_str, PHOTO_PATH_LEN + 1, "C:/%02d%02d%05d%02d.jpg", ext->time.tm_min, ext->time.tm_sec, pnode->size, r_num);
    name_str[PHOTO_PATH_LEN] = '\0';
    strncpy(pnode->file_path, name_str, PHOTO_PATH_LEN + 1);
    r_num = r_num + 1;
    if(r_num > 10) r_num = 0;

    lv_fs_file_t file;
    lv_fs_res_t res = lv_fs_open(&file, name_str, LV_FS_MODE_WR);
    if(res == LV_FS_RES_OK) {
        uint32_t rn;
        res = lv_fs_write(&file, (void *)img_capture.data, img_capture.data_size, &rn);
        if(res != LV_FS_RES_OK) {
            printf("write file error,errno = %d\n", res);
            _lv_ll_remove((lv_ll_t *)album_get_photo_ll(), pnode);
            lv_mem_free(pnode);
        } else {
            printf("writen len rn = %d\n", rn);
            res = album_photo_path_write(name_str);
            if(res != LV_FS_RES_OK) {
                lv_fs_remove(name_str);
                _lv_ll_remove((lv_ll_t *)album_get_photo_ll(), pnode);
                lv_mem_free(pnode);
            }
        }
        lv_fs_close(&file);
    } else {
        printf("open file error,errno = %d\n", res);
        _lv_ll_remove((lv_ll_t *)album_get_photo_ll(), pnode);
        lv_mem_free(pnode);
    }
    if(img_capture.data) {
        lv_mem_aligned_free((void *)img_capture.data);
        img_capture.data = NULL;
    }
    return res;
}
#endif

static void camera_save_failed_create(int32_t error)
{
    lv_obj_t * cont_bg = lv_cont_create(camera_get_obj(), NULL);
    lv_obj_set_size(cont_bg, LV_HOR_RES, LV_VER_RES);
    lv_obj_add_style(cont_bg, LV_CONT_PART_MAIN, &lv_watch_black_tight);

    lv_obj_t * img_fail = lv_img_create(cont_bg, NULL);
    lv_img_set_src(img_fail, ICON_CANCEL);
    lv_obj_align(img_fail, NULL, LV_ALIGN_IN_TOP_MID, 0, 30);

    lv_obj_t * label = lv_label_create(cont_bg, NULL);
    lv_label_set_text_id(label, WATCH_TEXT_ID_SAVE_FAILED);
    lv_obj_add_style(label, LV_LABEL_PART_MAIN, &lv_watch_font30);
    lv_label_set_align(label, LV_LABEL_ALIGN_CENTER);
    lv_obj_align(label, img_fail, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

    lv_obj_t * r_label = lv_label_create(cont_bg, NULL);
    if(error == CRANE_CAMERA_ERROR_OUTOFMEMORY)
         lv_label_set_text_id(r_label, WATCH_TEXT_ID_OUT_OF_MEM);
    else if(error == CRANE_CAMERA_ERROR_BADARGUMENT)
        lv_label_set_text_id(r_label, WATCH_TEXT_ID_FILE_ERROR);
    else if(error == CRANE_CAMERA_ERROR_INVALIDOPERATION)
        lv_label_set_text_id(r_label, WATCH_TEXT_ID_OPERATION_ERROR);
    else
        lv_label_set_text_id(r_label, WATCH_TEXT_ID_UNKONWN);
    lv_obj_add_style(r_label, LV_LABEL_PART_MAIN, &lv_watch_font20);
    lv_label_set_align(r_label, LV_LABEL_ALIGN_CENTER);
    lv_obj_align(r_label, label, LV_ALIGN_OUT_BOTTOM_MID, 0, 10);

    lv_camera_obj_ext_t * ext = camera_get_ext();
    ext->timer = Hal_Timer_Start(1000, camera_save_failed_timer_cb, cont_bg, false);
}

#if 0
static void camera_delete_create(void)
{
    lv_obj_t * par = camera_get_obj();
    lv_obj_t * bg = lv_cont_create(par, NULL);
    lv_obj_set_size(bg, LV_HOR_RES, LV_VER_RES);
    lv_obj_set_style_local_bg_color(bg, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xB6, 0xF7, 0xFF));

    lv_obj_t * img_to_del = lv_img_create(bg, NULL);
    lv_obj_set_pos(img_to_del, 70, 16);
    lv_img_cache_invalidate_src(&img_capture);
    img_capture.header.w = 100;
    img_capture.header.h = 100;
    lv_img_set_src(img_to_del, &img_capture);

    lv_obj_t * label_q = lv_label_create(bg, NULL);
    lv_label_set_text_id(label_q, WATCH_TEXT_ID_DEL_Q);
    lv_obj_add_style(label_q, LV_LABEL_PART_MAIN, &lv_watch_font20_black);
    lv_obj_align(label_q, img_to_del, LV_ALIGN_OUT_BOTTOM_MID, 0, 15);

    lv_obj_t * btn_cancel = lv_btn_create(bg, NULL);
    lv_obj_set_size(btn_cancel, 100, 56);
    lv_obj_set_style_local_bg_color(btn_cancel, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0x47, 0xA6, 0xFF));
    lv_obj_set_style_local_radius(btn_cancel, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 30);
    lv_obj_set_style_local_bg_color(btn_cancel, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_COLOR_MAKE(0x47, 0xA6, 0xFF));
    lv_obj_set_style_local_radius(btn_cancel, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 30);
    lv_obj_align(btn_cancel, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 10, -10);
    lv_obj_set_event_cb(btn_cancel, camera_delete_cancel_btn_event_cb);
    lv_obj_t * label_cancel = lv_label_create(btn_cancel, NULL);
    lv_label_set_text_id(label_cancel, WATCH_TEXT_ID_CANCEL);
    lv_obj_add_style(label_cancel, LV_LABEL_PART_MAIN, &lv_watch_font30);

    lv_obj_t * btn_ok = lv_btn_create(bg, btn_cancel);
    lv_obj_set_style_local_bg_color(btn_ok, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_MAKE(0xFF, 0x6F, 0x91));
    lv_obj_set_style_local_radius(btn_ok, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, 30);
    lv_obj_set_style_local_bg_color(btn_ok, LV_BTN_PART_MAIN, LV_STATE_PRESSED, LV_COLOR_MAKE(0xFF, 0x6F, 0x91));
    lv_obj_set_style_local_radius(btn_ok, LV_BTN_PART_MAIN, LV_STATE_PRESSED, 30);
    lv_obj_align(btn_ok, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, -10, -10);
    lv_obj_set_event_cb(btn_ok, camera_delete_ok_btn_event_cb);
    lv_obj_t * label_ok = lv_label_create(btn_ok, label_cancel);
    lv_label_set_text_id(label_ok, WATCH_TEXT_ID_OK);
}
#endif

static void camera_save_failed_timer_cb(void * param)
{
    if(lv_watch_get_activity_obj(ACT_ID_CAMERA) == NULL)
        return;
    lv_obj_t * obj = camera_get_obj();
    lv_obj_del((lv_obj_t *)param);
    lv_task_set_prio(preview_task, LV_TASK_PRIO_HIGH);
    lv_camera_obj_ext_t * ext = lv_obj_get_ext_attr(obj);
    ext->timer = NULL;
}

#if 0
static void camera_delete_cancel_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e)
    {
        lv_obj_del(lv_obj_get_parent(btn));
        lv_img_cache_invalidate_src(&img_capture);
        img_capture.header.w = 240;
        img_capture.header.h = 240;
    }
}

static void camera_delete_ok_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e)
    {
        lv_obj_t * obj = camera_get_obj();
        lv_obj_clean(obj);

        camera_create_shoot(obj);
        camera_create_option(obj);

        if(img_capture.data) {
            lv_mem_aligned_free((void *)img_capture.data);
            img_capture.data = NULL;
        }
        lv_task_set_prio(preview_task, LV_TASK_PRIO_HIGH);
    }
}
#endif

static void camera_outmem_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;
    if(LV_EVENT_CLICKED == e)
    {
        lv_obj_del(lv_obj_get_parent(btn));

        /*if(img_capture.data) {
            lv_mem_aligned_free((void *)img_capture.data);
            img_capture.data = NULL;
        }*/
        lv_task_set_prio(preview_task, LV_TASK_PRIO_HIGH);
    }
}

#if 0
static void camera_save_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;
    if(LV_EVENT_CLICKED == e)
    {
        lv_camera_obj_ext_t * ext = camera_get_ext();
        if(ext->timer) {
            Hal_Timer_Stop(ext->timer);
            ext->timer = NULL;
        }
        uint8_t photo_cnt = album_photo_ll_get_nodecnt();
        lv_obj_t * obj = camera_get_obj();
        if(photo_cnt >= PHOTO_MAX_COUNT) {
            camera_out_of_memory_create(obj);
        } else {
            if(camera_save_img_capture() == LV_FS_RES_OK) {
                lv_obj_clean(obj);
                camera_create_shoot(obj);
                camera_create_option(obj);
                lv_task_set_prio(preview_task, LV_TASK_PRIO_HIGH);
            } else {
                camera_save_failed_create();
            }
        }
    }
}

static void camera_share_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e)
    {
        lv_camera_obj_ext_t * ext = camera_get_ext();
        if(ext->timer) {
            Hal_Timer_Stop(ext->timer);
            ext->timer = NULL;
        }
#if USE_LV_BLUETOOTH != 0
        album_select_share_way(camera_get_obj());
#else
        voice_msg_create(NULL, 1, NULL);
#endif
    }
}

static void camera_delete_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;

    if(LV_EVENT_CLICKED == e)
    {
        lv_camera_obj_ext_t * ext = camera_get_ext();
        if(ext->timer) {
            Hal_Timer_Stop(ext->timer);
            ext->timer = NULL;
        }
        camera_delete_create();
    }
}
#endif

static void camera_back_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e)
    {
        camera_prepare_destory(camera_get_activity_obj());
        lv_obj_del(camera_get_activity_obj());
    }
}

static void camera_imgview_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    if(LV_EVENT_CLICKED == e)
    {
        lv_camera_obj_ext_t * ext = camera_get_ext();
        if(ext->timer) {
            Hal_Timer_Stop(ext->timer);
            ext->timer = NULL;
        }
        Hal_Camera_Stop_Preview(0);
        lv_obj_set_hidden(ext->img, true);
        lv_mem_free(img_camera.data);
        img_camera.data = NULL;
        lv_task_del(preview_task);
        preview_task = NULL;
        /* lv_img_cache_invalidate_src(&img_capture);
        if(img_capture.data) {
            lv_mem_aligned_free((void *)img_capture.data);
            img_capture.data = NULL;
        }*/

        //set a black temp obj
        lv_obj_set_hidden(ext->cont, false);

        album_create_from_camera();
    }
}

static void camera_shoot_btn_event_cb(lv_obj_t * btn, lv_event_t e)
{
    (void)btn;
    static uint8_t r_num = 0;
    if(LV_EVENT_CLICKED == e)
    {
        lv_camera_obj_ext_t * ext = camera_get_ext();
        if((ext == NULL) || (preview_task == NULL)) {
            printf("%s: camera destroyed!\n", __FUNCTION__);
            return;
        }

        uint8_t photo_cnt = album_photo_ll_get_nodecnt();
        if(photo_cnt >= PHOTO_MAX_COUNT) {
            camera_out_of_memory_create(camera_get_obj());
            return;
        }

        uint32_t fs_total = 0;
        uint32_t fs_free = 0;
        lv_fs_free_space('C', &fs_total, &fs_free);
        printf("%s: space total = %dB, free = %dB!!\n", __FUNCTION__, fs_total, fs_free);
        if(fs_free < 100 * 1024) {
            camera_out_of_memory_create(camera_get_obj());
            return;
         }

        cam_capture_t cap_param;
        int32_t error = CRANE_CAMERA_ERROR_NONE;
        cap_param.width = 240;
        cap_param.height = 240;

        album_photo_info_t * pnode = NULL;
        pnode = (album_photo_info_t *)_lv_ll_ins_tail((lv_ll_t *)album_get_photo_ll());
        if(pnode == NULL) {
            printf("%s: add node failed!!\n", __FUNCTION__);
            camera_out_of_memory_create(camera_get_obj());
            return;
        }

        char name_str[PHOTO_PATH_LEN + 1];
        memset(name_str, 0, PHOTO_PATH_LEN + 1);
        pnode->selected = 0;
        pnode->index = album_photo_ll_get_nodecnt() - 1;
        Hal_Rtc_Gettime(&(ext->time));
        snprintf(name_str, PHOTO_PATH_LEN + 1, "C:/%02d%02d%02d%02d%03d.jpg", ext->time.tm_mday, ext->time.tm_hour, ext->time.tm_min, ext->time.tm_sec, r_num);
        name_str[PHOTO_PATH_LEN] = '\0';
        strncpy(pnode->file_path, name_str, PHOTO_PATH_LEN + 1);
        r_num = r_num + 1;
        if(r_num > 100) r_num = 0;

        lv_fs_file_t file;
        lv_fs_res_t res = lv_fs_open(&file, name_str, LV_FS_MODE_WR);
        if(res == LV_FS_RES_OK) {
            lv_task_set_prio(preview_task, LV_TASK_PRIO_OFF);
            lv_obj_set_hidden(ext->cont, false);
            lv_refr_now(NULL);

            int32_t * fd = (int32_t*)file.file_d;
            error =  Hal_Camera_Capture(&cap_param, *fd);
            if (error == CRANE_CAMERA_ERROR_NONE) {
                res = album_photo_path_write(name_str);
                if(res != LV_FS_RES_OK) {
                    lv_fs_remove(name_str);
                    _lv_ll_remove((lv_ll_t *)album_get_photo_ll(), pnode);
                    lv_mem_free(pnode);
                    printf("%s: save photo path failed, name = %s\n", __FUNCTION__, name_str);
                } else {
                    pnode->size = cap_param.jpeg_size;
                    printf("%s:capture&save photo success!!, size = %d, w= %d, h = %d\n",
                      __FUNCTION__, pnode->size, cap_param.width, cap_param.height);
                }
                lv_task_set_prio(preview_task, LV_TASK_PRIO_HIGH);
            } else {
                printf("%s: save photo failed, errno = %d\n", __FUNCTION__, error);
                _lv_ll_remove((lv_ll_t *)album_get_photo_ll(), pnode);
                lv_mem_free(pnode);
                camera_save_failed_create(error);
            }
            lv_fs_close(&file);
            lv_obj_set_hidden(ext->cont, true);
            lv_refr_now(NULL);
        } else {
            printf("%s:open file error,errno = %d\n", __FUNCTION__, res);
            _lv_ll_remove((lv_ll_t *)album_get_photo_ll(), pnode);
            lv_mem_free(pnode);
        }
    }
}

static void camera_destroy_task(lv_task_t * task)
{
     Hal_Camera_Stop_Preview(0);
}

static void camera_prepare_destory(lv_obj_t * activity_obj)
{
    lv_camera_obj_ext_t * ext = camera_get_ext();
    if(ext->timer) {
        Hal_Timer_Stop(ext->timer);
        ext->timer = NULL;
    }
    lv_task_t * des_task = lv_task_create(camera_destroy_task, 20, LV_TASK_PRIO_HIGH, NULL);
    lv_task_once(des_task);
    lv_watch_png_cache_all_free();
    lv_mem_free(img_camera.data);
    img_camera.data = NULL;
    if(preview_task) {
        lv_task_del(preview_task);
        preview_task = NULL;
    }
   /* lv_img_cache_invalidate_src(&img_capture);
    if(img_capture.data) {
        lv_mem_aligned_free((void *)img_capture.data);
        img_capture.data = NULL;
    }*/
    album_photo_ll_destroy();
}

static void camera_preview_task(lv_task_t * task)
{
    lv_obj_t * cam_obj = lv_watch_get_activity_obj(ACT_ID_CAMERA);
    lv_obj_t * top_obj = lv_watch_get_top_activity_obj();
    lv_area_t img_cords;

    lv_obj_get_coords(cam_obj, &img_cords);
    if(img_cords.x1 != 0 || top_obj != cam_obj) {
         return;
    }
    lv_img_cache_invalidate_src(&img_camera);
    if(Hal_Camera_Preview((uint8_t *)img_camera.data)) {
        //update the src of img.
        lv_camera_obj_ext_t * ext = camera_get_ext();
        lv_img_set_src(ext->img, &img_camera);
    }
    lv_task_set_period(preview_task, 30);
}

#if 0
static void camera_autosave_timer_func(void * param)
{
    uint8_t photo_cnt = album_photo_ll_get_nodecnt();
    lv_obj_t * obj = camera_get_obj();
    lv_camera_obj_ext_t * ext = lv_obj_get_ext_attr(obj);
    ext->timer = NULL;
    if(photo_cnt >= PHOTO_MAX_COUNT)  {
        camera_out_of_memory_create(obj);
    } else {
        if(camera_save_img_capture() == LV_FS_RES_OK) {
            lv_obj_clean(obj);
            camera_create_shoot(obj);
            camera_create_option(obj);
            lv_task_set_prio(preview_task, LV_TASK_PRIO_HIGH);
        } else {
            camera_save_failed_create();
        }
    }
}
#endif
#endif /*USE_LV_WATCH_CAMERA*/
